//
// Created by 21126 on 2023/5/19.
//
#include "U2_E1.h"

unsigned char HT16K33_ADDRESS_E1[4] = {0x70, 0x71, 0x72, 0x73};
unsigned char PCA9685_ADDRESS_E1[4] = {0x60, 0x61, 0x62, 0x63};

const unsigned char TUBE_NUMS[11][2] = {
    //e d c b a x x x x x x x x bp g f
    {0xF8, 0x01},// 数字0 : 11111100
    {0x30, 0x00},// 数字1 : 01100000
    {0xD8, 0x02},// 数字2 : 11011010
    {0x78, 0x02},// 数字3 : 11110010
    {0x30, 0x03},// 数字4 : 01100110
    {0x68, 0x03},// 数字5 : 10110110
    {0xE8, 0x03},// 数字6 : 10111110
    {0x38, 0x00},// 数字7 : 11100000
    {0xF8, 0x03},// 数字8 : 11111110
    {0x38, 0x03},// 数字9 : 11100110
    {0x00, 0x00}
};

void u2_setPWM(int fd, unsigned char slave_address, unsigned char num, __u16 on, __u16 off)
{
    i2c_write_byte(fd, slave_address, LED0_ON_L + 4 * num, on);
    i2c_write_byte(fd, slave_address, LED0_ON_H + 4 * num, on >> 8);
    i2c_write_byte(fd, slave_address, LED0_OFF_L + 4 * num, off);
    i2c_write_byte(fd, slave_address, LED0_OFF_H + 4 * num, off >> 8);
}

void u2_setPWM_off(int fd, unsigned char slave_address)
{
    i2c_write_byte(fd, slave_address, ALLLED_ON_L, 0);
    i2c_write_byte(fd, slave_address, ALLLED_ON_H, 0);
    i2c_write_byte(fd, slave_address, ALLLED_ON_L, 0);
    i2c_write_byte(fd, slave_address, ALLLED_ON_H, 0);
}

i2c_addr_def u2_e1_led_init(int fd)
{
    i2c_addr_def result;
    unsigned char real_slave_address;

    result.flag = 0;

    if (i2c_detect(fd, PCA9685_ADDRESS_E1, sizeof(PCA9685_ADDRESS_E1), &real_slave_address) >= 0)
    {
        result.fd = fd;
        result.addr = real_slave_address;
        result.flag = 1;

        u2_pca9685_init(result.fd, result.addr);
    }

    return result;
}

i2c_addr_def u2_e1_tube_init(int fd)
{
    i2c_addr_def result;
    unsigned char real_slave_address;

    result.flag = 0;

    if (i2c_detect(fd, HT16K33_ADDRESS_E1, sizeof(HT16K33_ADDRESS_E1), &real_slave_address) >= 0)
    {
        result.fd = fd;
        result.addr = real_slave_address;
        result.flag = 1;

        u2_ht16k33_init(result.fd, result.addr);
    }

    return result;
}

void u2_pca9685_init(int fd, unsigned char slave_address)
{
    i2c_write_byte(fd, slave_address, PCA9685_MODE1, 0x00);
    u2_setPWM_off(fd, slave_address);
}

void u2_ht16k33_init(int fd, unsigned char slave_address)
{
    i2c_write_cmd(fd, slave_address, SYSTEM_ON_E1);
    i2c_write_cmd(fd, slave_address, ROW_OUTPUT);
    u2_ht16k33_RAM_init(fd, slave_address);
    i2c_write_cmd(fd, slave_address, TUBE_ON);
}

void u2_ht16k33_RAM_init(int fd, unsigned char slave_address)
{
    for (int i = 2; i < 10; ++i)
        i2c_write_byte(fd, slave_address, i, 0x00);
}

void u2_display_tube(__u16 value, i2c_addr_def e1_tube_addr)
{
    if (value > 9999)
        return;

    unsigned char buf[4];
    unsigned char i, bits;

    for (i = 0; i < 4 && value; i++)
    {
        buf[i] = value % 10;
        value /= 10;
    }

    bits = i == 0 ? 1 : i;

    u2_ht16k33_RAM_init(e1_tube_addr.fd, e1_tube_addr.addr);

    for (i = 4; i > 4 - bits; --i)
    {
        unsigned char addr = i * 2;
        i2c_write_byte(e1_tube_addr.fd, e1_tube_addr.addr, addr, TUBE_NUMS[buf[4 - i]][0]);
        i2c_write_byte(e1_tube_addr.fd, e1_tube_addr.addr, addr + 1, TUBE_NUMS[buf[4 - i]][1]);
    }
}